
// MyMusicPlayerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MyMusicPlayer.h"
#include "MyMusicPlayerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About
UINT ThreadOpenFile(LPVOID pParam)
{  
	CMyMusicPlayerDlg* pDlg=(CMyMusicPlayerDlg*) pParam;
	pDlg->openfile();
	return 0;
}
UINT ThreadPlayPause(LPVOID pParam)
{  
	CMyMusicPlayerDlg* pDlg=(CMyMusicPlayerDlg*) pParam;
	pDlg->PlayPause();
	return 0;
}

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CMyMusicPlayerDlg dialog




CMyMusicPlayerDlg::CMyMusicPlayerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMyMusicPlayerDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMyMusicPlayerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STC_PLAYING, m_stcPlaying);
	DDX_Control(pDX, IDC_SLD_LIFE, m_SliderTimeLife);
	DDX_Control(pDX, IDC_STC_TIMEPLAY, m_stcTimePlay);
	DDX_Control(pDX, IDC_STC_TIME_TOTAL, m_stcTimeTotal);
	DDX_Control(pDX, IDC_SLD_VOLUME, m_sliderVolume);
	DDX_Control(pDX, IDC_BTN_PLAY, m_btnPlay);
	DDX_Control(pDX, IDC_BTN_STOP, m_btnStop);
}

BEGIN_MESSAGE_MAP(CMyMusicPlayerDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BTN_PLAY, &CMyMusicPlayerDlg::OnBnClickedBtnPlay)
	ON_BN_CLICKED(IDC_BTN_STOP, &CMyMusicPlayerDlg::OnBnClickedBtnStop)
	ON_WM_TIMER()
	/*ON_WM_SIZE()
	ON_WM_SIZING()*/
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLD_VOLUME, &CMyMusicPlayerDlg::OnNMReleasedcaptureSldVolume)
	ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLD_LIFE, &CMyMusicPlayerDlg::OnNMReleasedcaptureSldLife)
	ON_COMMAND(ID_FILE_OPENFILE, &CMyMusicPlayerDlg::OnFileOpenfile)
	ON_COMMAND(ID_FILE_EXIT, &CMyMusicPlayerDlg::OnFileExit)
	ON_COMMAND(ID_CONTROL_PAUSE, &CMyMusicPlayerDlg::OnControlPausePlay)
	ON_COMMAND(ID_CONTROL_STOP, &CMyMusicPlayerDlg::OnControlStop)
END_MESSAGE_MAP()

//BEGIN_EASYSIZE_MAP(CMyMusicPlayerDlg)
//	EASYSIZE(IDC_STC_PLAYING,ES_BORDER,ES_BORDER,ES_BORDER,ES_KEEPSIZE,0)
//
//
//END_EASYSIZE_MAP





// CMyMusicPlayerDlg message handlers

BOOL CMyMusicPlayerDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	m_Menu.LoadMenuW(IDR_MY_MENU);
	SetMenu(&m_Menu);

	pGraphBuilder		= NULL;
	pMediaControl		= NULL;
	pMediaSeeking		= NULL;
	pMediaEventEx       = NULL;
	hOwner				= NULL;
	totalDuration		= 0;
	timeElapsed			= 0;
	
	m_sliderVolume.SetRange(-10,0);
	m_sliderVolume.SetPos(-5);
	lvolume=0;
    m_bInit=false;
	
	Initialize(this->m_hWnd);
	//INIT_EASYSIZE;
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMyMusicPlayerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMyMusicPlayerDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMyMusicPlayerDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CMyMusicPlayerDlg::Initialize(HWND owner)
{
    HRESULT hr;
	//init COM
	hr=CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
	if(FAILED(hr))
	{
		MessageBox(_T("Error ->COM init is fail"));
	}
	//create instace and query interface
	hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&pGraphBuilder);
	if(FAILED(hr))
	{
		MessageBox(_T("Error -> could not create the FilterGraphManager"));
		pGraphBuilder->Release();
		pGraphBuilder=NULL;
		CoUninitialize();
	}
	//query interface
	hr = pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
	hr = pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void**)&pMediaSeeking);
	hr = pGraphBuilder->QueryInterface(IID_IMediaEventEx, (void**)&pMediaEventEx);
	hr = pGraphBuilder->QueryInterface(IID_IBasicAudio,(void**)&pAudio);
	if (!pMediaControl || !pMediaSeeking || !pMediaEventEx|| !pAudio)
	{
		MessageBox(_T("Critical error, error getting references Error"));
		pMediaControl->Release();
		pMediaControl=NULL;
		pMediaSeeking->Release();
		pMediaSeeking=NULL;
		pMediaEventEx->Release();
		pMediaEventEx=NULL;
		pAudio->Release();
		pAudio		 =NULL;
		//CoUninitialize();
	}
	// hOwner stores the handle to the dialog
	hOwner = owner;
	m_strPlay=L"Play";
	m_strPause=L"Pause";
	m_btnPlay.SetWindowTextW(m_strPlay);
	pMediaEventEx->SetNotifyWindow((OAHWND)hOwner, WM_GRAPHNOTIFY, 0);
	m_bPlaying=false;
	lTotalDuration=0;
	



}

int CMyMusicPlayerDlg::StartPlayingFile()
{
	CMyMusicPlayerDlg dlg;
 
   if(m_bInit)
	{  //---check da chay het chuong trinh chua----
		ReleaseVal();
		//Initialize(this->m_hWnd);
		m_bInit=false;
	}
   else
   {

    char totalTime[MAX_SIZE];
	LONGLONG lDuration100NanoSecs = 0;
	pGraphBuilder->RenderFile((LPCWSTR)m_strPathFile, NULL);
	
	// get the time in units of 100 ns
	pMediaSeeking->GetDuration(&lDuration100NanoSecs);
	// get the total duration in seconds

	totalDuration = (long)(lDuration100NanoSecs/10000000);//10^-7
	// normalising to 100, see note above
	step = (float)100/totalDuration;

	// get the total time in printable format all divs and mods are to get hh:mm:ss
	sprintf(totalTime, "%02u:%02u:%02u", (totalDuration/3600)%60, (totalDuration/60)%60, (totalDuration%60));
	CString strTime(totalTime);
	int     sizeOfString2 = (strTime.GetLength() + 1);
	LPTSTR  lpsz2 = new TCHAR[ sizeOfString2 ];
	_tcscpy_s(lpsz2, sizeOfString2, strTime);
	m_stcTimeTotal.SetWindowTextW(lpsz2);
	//------here we will have file name of songs------

	//m_stcPlaying.SetWindowTextW((LPCTSTR)m_strNameFile);
	//dlg.SetWindowTextW(m_strNameFile);

	m_bPlaying = true;

	// Enable the play/pause button, 
	m_btnPlay.SetWindowTextW(m_strPause);

	// set the range of the progress bar
	m_SliderTimeLife.SetRange(0,100);
	SetTimer(MY_TIMEREVENT,1000,(TIMERPROC)NULL);
	// play the file
	pMediaControl->Run();
	HRESULT hr= pAudio->get_Volume(&lvolume);
	int nvalSlider=lvolume/(1000);
	m_sliderVolume.SetPos((int)nvalSlider);
	m_bInit=true;
   }

	return 1;

}
int CMyMusicPlayerDlg::PlayPause()
{

if(pMediaControl != NULL)
	{
		if(m_bPlaying)
		{
			pMediaControl->Pause();
			m_bPlaying=false;
			m_btnPlay.SetWindowTextW(m_strPlay);
		}
		else
		{
			pMediaControl->Run();
			m_bPlaying=true;
			m_btnPlay.SetWindowTextW(m_strPause);
		}
	}
	return 1;

}
int CMyMusicPlayerDlg::DoTimeStuff()
{
    char time[MAX_SIZE] = "";
	int pos = 0;
	if (!m_bPlaying  || timeElapsed >= totalDuration)
	{
		return 0;
	}
	timeElapsed++;
	pos = (int)((float)step*(float)timeElapsed);
	m_SliderTimeLife.SetPos(pos);

	sprintf(time, "%02u:%02u:%02u", (timeElapsed/3600)%60, (timeElapsed/60)%60, timeElapsed%60);

	//
	CString strTime(time);
	int     sizeOfString2 = (strTime.GetLength() + 1);
	LPTSTR  lpsz2 = new TCHAR[ sizeOfString2 ];
	_tcscpy_s(lpsz2, sizeOfString2, strTime);
	m_stcTimePlay.SetWindowTextW(lpsz2);

	return 1;

}
void CMyMusicPlayerDlg::OnTimer(UINT_PTR nIDEvent)
{
  if(nIDEvent==MY_TIMEREVENT)
  DoTimeStuff();
  CDialog::OnTimer(nIDEvent);
  

}
int CMyMusicPlayerDlg::DoStop()
{
	if (pMediaControl != NULL)
	{
//		HWND hWnd;
		REFERENCE_TIME rt = 0;
		if(m_bPlaying)
		{
			pMediaControl->Stop();
			m_bPlaying=false;
			m_btnPlay.SetWindowTextW(m_strPlay);
		}
        if(pMediaSeeking)
		{
			pMediaSeeking->SetPositions(&rt,AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning);
		}


		//reset playing to zero
		m_SliderTimeLife.SetPos(0);
		timeElapsed=0;
		m_stcTimePlay.SetWindowTextW(L"00:00:00");
	}
	return 1;

}
BOOL CMyMusicPlayerDlg::PreTranslateMessage(MSG *pMsg)
{
	if(pMsg->message== WM_GRAPHNOTIFY)
		HanldeEventFromGraph();
	return CWnd::PreTranslateMessage(pMsg);

}
int CMyMusicPlayerDlg::HanldeEventFromGraph()
{
    HRESULT hr = S_OK;
	long evCode, param1,param2;
	if(!pMediaEventEx)
	{
		AfxMessageBox(_T("MediaEventEx interface error"));
		return 0;
	}
	while (SUCCEEDED(pMediaEventEx->GetEvent(&evCode, &param1, &param2, 0)))
	{
		switch(evCode)
		{
			case EC_COMPLETE:
				//StartPlayingFile();
				DoStop();
			break;
			
		}
		hr = pMediaEventEx->FreeEventParams(evCode, param1, param2);
	}
	return 1;

}
int CMyMusicPlayerDlg::ReleaseVal()
{
    DoStop();
	if(pMediaControl)
	{
		pMediaControl->Release(); 
		pMediaControl = NULL;
	}

	if(pMediaSeeking)
	{
		pMediaSeeking->Release(); 
		pMediaSeeking = NULL;
	}

	if(pMediaEventEx)
	{
		pMediaEventEx->Release();
		pMediaEventEx = NULL;
	}
	if(pGraphBuilder)
	{
		pGraphBuilder->Release();
		pGraphBuilder = NULL;
	}
	if(pAudio)
	{
		pAudio->Release();
		pAudio = NULL;
	}
	return 1;

}



void CMyMusicPlayerDlg::OnBnClickedBtnPlay()
{
	// TODO: Add your control notification handler code here
	PlayPause();
}

void CMyMusicPlayerDlg::OnBnClickedBtnStop()
{
	// TODO: Add your control notification handler code here
	DoStop();
}



void CMyMusicPlayerDlg::OnNMReleasedcaptureSldVolume(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: Add your control notification handler code here
	*pResult = 0;
	int nPos=m_sliderVolume.GetPos();
	HRESULT hr;
	if(nPos>-8) //if in rangle[-8,0] volume will get about [-5000,0]
	{
		int val= 500;
		lvolume=nPos*val;
	}
	else //and about [-10,-8] volume will get [-10000, -5000 ]
	{
		int val = 1000;
		lvolume = nPos*val;
	}
	hr = pAudio->put_Volume(lvolume);

}





void CMyMusicPlayerDlg::OnNMReleasedcaptureSldLife(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: Add your control notification handler code here
	*pResult = 0;
	HRESULT hr;
	int nPos= m_SliderTimeLife.GetPos();
//
	pMediaSeeking->GetDuration(&lTotalDuration);
	hr=pMediaControl->Pause();
	REFERENCE_TIME rtNew = (lTotalDuration * nPos) / 100;
	hr = pMediaSeeking->SetPositions(&rtNew, AM_SEEKING_AbsolutePositioning,
                             NULL,AM_SEEKING_NoPositioning);
	hr=pMediaSeeking->GetCurrentPosition(&rtNew);
	hr=pMediaControl->Run();
    m_SliderTimeLife.SetPos(rtNew/10000000);
	timeElapsed=rtNew/10000000;
	char time[MAX_SIZE] = "";
	sprintf(time, "%02u:%02u:%02u", (timeElapsed/3600)%60, (timeElapsed/60)%60, timeElapsed%60);
	//show time play when you edit position
	CString strTime(time);
	int     sizeOfString2 = (strTime.GetLength() + 1);
	LPTSTR  lpsz2 = new TCHAR[ sizeOfString2 ];
	_tcscpy_s(lpsz2, sizeOfString2, strTime);
	m_stcTimePlay.SetWindowText(lpsz2);


}
void CMyMusicPlayerDlg::openfile()
{
    CString strFilter = _T("All files| *.mp3;*.avi;*.wmv;*.*|");
	strFilter += _T("video file (*.avi;*.wmv)|*.avi;*.wmv|");
	strFilter += _T("mp3 file (*.mp3)|*.mp3|");

	CFileDialog Load(TRUE, NULL, NULL, OFN_FILEMUSTEXIST| OFN_HIDEREADONLY |OFN_ALLOWMULTISELECT,strFilter, NULL);
	Load.m_ofn.lpstrTitle= _T("Open Media file");
	if (Load.DoModal() == IDOK) 
	{
		m_strPathFile=Load.GetPathName();
		m_strNameFile=Load.GetFileName();
		CWnd *cwnd = GetDlgItem(IDC_PRG_STATUS);
		//ReleaseVal();
		StartPlayingFile();
	}
}

void CMyMusicPlayerDlg::OnFileOpenfile()
{
	
	AfxBeginThread(ThreadOpenFile,this);

}


void CMyMusicPlayerDlg::OnFileExit()
{
	// TODO: Add your command handler code here
	PostQuitMessage(0);
}

//void CMyMusicPlayerDlg::OnSize(UINT nType, int cx, int cy)
//{
//	CDialog::OnSize(nType,cx,cy);
//	UPDATE_EASYSIZE;
//}
//
//
//void CMyMusicPlayerDlg::OnSizing(UINT fwSide, LPRECT pRect)
//{
//	CDialog::OnSizing(fwSide,pRect);
//	EASYSIZE_MINSIZE(400,300,fwSide,pRect);
//
//}

void CMyMusicPlayerDlg::OnControlPausePlay()
{
	// TODO: Add your command handler code here
// AfxBeginThread(ThreadPlayPause);

}

void CMyMusicPlayerDlg::OnControlStop()
{
	// TODO: Add your command handler code here
if (pMediaControl != NULL)
	{
//		HWND hWnd;
		REFERENCE_TIME rt = 0;
		if(m_bPlaying)
		{
			pMediaControl->Stop();
			m_bPlaying=false;
			m_btnPlay.SetWindowTextW(m_strPlay);
		}
        if(pMediaSeeking)
		{
			pMediaSeeking->SetPositions(&rt,AM_SEEKING_AbsolutePositioning,NULL,AM_SEEKING_NoPositioning);
		}


		//reset playing to zero
		m_SliderTimeLife.SetPos(0);
		timeElapsed=0;
		m_stcTimePlay.SetWindowTextW(L"00:00:00");
	}

}
